#include "ota_manager.h"
#include "auth_manager.h"
#include "boot_api.h"
#include "config_api.h"
#include "fal.h"
#include "interaction_manager.h"
#include "manager_queue_comm.h"
#include "module_queue_struct.h"
#include "net_down.h"
#include "uc_wiota_api.h"
#include <rtdevice.h>
#include <rthw.h>
#include <rtthread.h>

#define DBG_ENABLE
#define DBG_SECTION_NAME "ota"
#include "uc_log.h"

#define GATEWAY_BIN_SIZE (1 * 1024 * 1024) // 升级时大小校验，至少为1M，小于则说明网关镜像不对
#define EXTERN_MCU "ex_mcu"

/**
 * @brief 终端OTA升级信息结构体
 *
 */
typedef struct
{
    app_ps_ota_upgrade_info_t upgrade_info; /**< 网关与终端OTA数据交互的结构体 */
    ota_state_e ota_state;                  /**< OTA升级流程状态 */
    rt_timer_t send_end_timer;              /**< OTA升级包发送完成后启动的定时器，超时时表示OTA结束*/
    rt_timer_t sending_timer;               /**< OTA升级包或缺失数据包发送定时器，超时一次发送一次数据 */
    unsigned int single_block_send_time;    /**< OTA单包发送时间，由于OTA数据包较大，不建议一次性丢给AP，故间隔时间发送 */
    unsigned char send_miss_data;           /**< 收到缺失数据请求后置1，表示有缺失包需要发送 */
    unsigned int ota_op_address;            /**< OTA镜像存储地址，0 */
    unsigned int block_count;               /**< OTA数据分包发送的包数，512个字节一个包 */
    unsigned int miss_data_num;             /**< 缺失数据包的个数 */
    unsigned char mask_map[28];             /**< 记录缺失数据包的mask，一个bit映射一个数据包的地址 */
    char file_name[40];                     /**< OTA文件路径 */
    int error_cnt;                          /**< OTA过程出错次数，当连续大于5次后，OTA终止 */
    unsigned int sending_total_len;         /**< OTA发送总长度 */
} ota_upgrade_info_t;

// OTA升级信息全局变量
static ota_upgrade_info_t g_ota_info = {0};

/**
 * @brief 将版本转化为数字，用于比较版本合法性和是否升级
 *
 * @param version       net下发的升级版本号
 * @return unsigned int 转化的版本数字
 */
static unsigned int manager_ota_version_to_number(char *version)
{
    char *string = version;
    char number_string[24] = {0};
    int m = 0, n = 0;

    while ((*string == 'v' || *string == 'V') && *string != 0)
        string++;

    while (*string != 0 && *string != '_')
    {
        if ('.' != *string)
        {
            number_string[m++] = *string;
            n++;
        }
        else if ('.' == *string)
        {
            while (n < 4)
            {
                number_string[m++] = '0';
                n++;
            }
            n = 0;
        }

        string++;
    }

    while (n < 4)
    {
        number_string[m++] = '0';
        n++;
    }

    return atoi(number_string);
}

/**
 * @brief 设置OTA状态
 *
 * @param state OTA状态，ota_state_e
 */
void manager_set_ota_state(ota_state_e state)
{
    TRACE_I("ota_state %d to %d", g_ota_info.ota_state, state);
    g_ota_info.ota_state = state;
}

/**
 * @brief 获取OTA状态
 *
 * @return ota_state_e OTA状态
 */
ota_state_e manager_get_ota_state(void)
{
    return g_ota_info.ota_state;
}

/**
 * @brief 设置OTA包类型，终端升级时需要
 *
 * @param type OTA包类型，升级包或缺失包
 */
static void manager_set_ota_packet_type(ota_packet_type_e type)
{
    TRACE_I("ota packet_type %d to %d", g_ota_info.upgrade_info.packet_type, type);
    g_ota_info.upgrade_info.packet_type = type;
}

/**
 * @brief 设置缺失数据发送标志，收到缺失数据请求后置1，缺失数据发送完成后置0
 *
 * @param flag
 */
static void manager_set_send_missing_data(unsigned char flag)
{
    TRACE_I("ota send_miss_data %d to %d", g_ota_info.send_miss_data, flag);
    g_ota_info.send_miss_data = flag;
}

/**
 * @brief 启动OTA发送结束定时器
 *
 */
static void manager_send_end_timer_start(void)
{
    if (RT_NULL != g_ota_info.send_end_timer)
    {
        rt_timer_start(g_ota_info.send_end_timer);
    }
}

/**
 * @brief 停止OTA发送结束定时器
 *
 */
static void manager_send_end_timer_stop(void)
{
    if (RT_NULL != g_ota_info.send_end_timer)
    {
        rt_timer_stop(g_ota_info.send_end_timer);
    }
}

/**
 * @brief 删除OTA发送结束定时器
 *
 */
static void manager_send_end_timer_del(void)
{
    if (RT_NULL != g_ota_info.send_end_timer)
    {
        rt_timer_delete(g_ota_info.send_end_timer);
        g_ota_info.send_end_timer = RT_NULL;
    }
}

/**
 * @brief 重置OTA发送结束定时器
 *
 */
static void manager_send_end_timer_reset(void)
{
    unsigned int timer_state = 0;
    unsigned int timeout = g_ota_info.single_block_send_time * 50;

    if (RT_NULL != g_ota_info.send_end_timer)
    {
        rt_timer_control(g_ota_info.send_end_timer, RT_TIMER_CTRL_GET_STATE, (void *)&timer_state);
        if (RT_TIMER_FLAG_ACTIVATED == timer_state)
        {
            rt_timer_control(g_ota_info.send_end_timer, RT_TIMER_CTRL_SET_TIME, (void *)&timeout);
            rt_timer_start(g_ota_info.send_end_timer);
        }
    }
}

/**
 * @brief 开启OTA发送定时器
 *
 */
static void manager_sending_timer_start(void)
{
    if (RT_NULL != g_ota_info.sending_timer)
    {
        rt_timer_start(g_ota_info.sending_timer);
    }
}

/**
 * @brief 停止OTA发送定时器
 *
 */
static void manager_sending_timer_stop(void)
{
    if (RT_NULL != g_ota_info.sending_timer)
    {
        rt_timer_stop(g_ota_info.sending_timer);
    }
}

/**
 * @brief 删除OTA发送定时器
 *
 */
static void manager_sending_timer_del(void)
{
    if (RT_NULL != g_ota_info.sending_timer)
    {
        rt_timer_delete(g_ota_info.sending_timer);
        g_ota_info.sending_timer = RT_NULL;
    }
}

/**
 * @brief 计算发送单次OTA数据包需要的时间，终端升级时需要
 *
 */
static void manager_calc_single_block_send_time(void)
{
    unsigned char symbol_length = uc_static_get_wiota_sys_cfg()->symbol_length;
    unsigned char bc_mcs = uc_static_get_wiota_rate_cfg()->broadcast_mcs;
    unsigned int frame_len = uc_wiota_get_frame_len();
    unsigned short mcs_len = 0;
    unsigned char send_round = uc_wiota_get_broadcast_send_round();

    const unsigned short MCS_TABLE_WITHOUT_CRC[4][8] = {
        {7, 9, 52, 66, 80, 0, 0, 0},
        {7, 15, 22, 52, 108, 157, 192, 0},
        {7, 15, 31, 42, 73, 136, 255, 297},
        {7, 15, 31, 63, 108, 220, 451, 619},
    };

    mcs_len = MCS_TABLE_WITHOUT_CRC[symbol_length][bc_mcs] - 2;
    g_ota_info.upgrade_info.mcs_len = mcs_len;
    g_ota_info.single_block_send_time = (((((OTA_BLOCK_SIZE + 150) / mcs_len + 1) / 7 + 1) * frame_len) / 1000 + 1) * send_round;

    TRACE_I("ota_calc, mcs_len %d, single_block_send_time %d",
            g_ota_info.upgrade_info.mcs_len, g_ota_info.single_block_send_time);
}

/**
 * @brief OTA发送结束超时定时器，当发送完所有OTA数据后启动该timer，超时时间内未收到丢失包请求，则OTA流程结束。
 *        超时时间内每收到一次丢失包请求，则重置timer超时时间，终端升级时需要
 *
 * @param para timer创建时传入的参数
 */
static void manager_handle_ota_send_end_msg(void *para)
{
    // 模拟NET APP线程发送给自身线程，处理OTA完成消息
    module_queue_communication(module_get_queue(GATEWAY_MANAGER_MODULE),
                               NET_APP_MODULE,
                               GATEWAY_MANAGER_MODULE,
                               OTA_UPGRADE_COMPLETE,
                               RT_NULL);
}

/**
 * @brief 发送单块OTA数据，开始时调用，定时器触发周期调用
 *
 */
static void manager_send_single_block_ota_data()
{
    // 模拟NET APP线程发送给自身线程，处理OTA数据包发送
    module_queue_communication(module_get_queue(GATEWAY_MANAGER_MODULE),
                               NET_APP_MODULE,
                               GATEWAY_MANAGER_MODULE,
                               OTA_UPGRADE_DATA_SENDING,
                               RT_NULL);
}

/**
 *
 * @brief OTA数据包发送定时器，触发周期为single_block_send_time，OTA状态为OTA_STATE_SENDING或收到丢失包请求后时开始，
 *        OTA发送完成后停止，OTA发送结束超时定时器触发时销毁
 *
 * @param para timer创建时传入的参数
 */
static void manager_handle_ota_sending_msg(void *para)
{
    manager_send_single_block_ota_data();
}

/**
 * @brief 处理网关升级
 *
 * @param file_size OTA文件大小
 */
static void manager_handle_gateway_upgrade(unsigned int file_size)
{
    TRACE_D("gateway ota_upgrade begins, file_name %s, file_size %d", g_ota_info.file_name, file_size);
    if (GATEWAY_BIN_SIZE > file_size)
    {
        TRACE_E("gateway bin maybe error, please check\n");
        manager_set_ota_state(OTA_STATE_STOP);
        return;
    }
    uc_set_uboot_mode(UC_UBOOT_OS_UPDATE);
    uc_set_file_params(file_size);
    uc_boot_cfg_save();

    if (0 != module_queue_communication(module_get_queue(WIOTA_APP_MODULE),
                                        GATEWAY_MANAGER_MODULE,
                                        WIOTA_APP_MODULE,
                                        WIOTA_APP_OTA_UPGRADE,
                                        RT_NULL))
    {
        manager_set_ota_state(OTA_STATE_STOP);
    }
    else
    {
        manager_set_ota_state(OTA_STATE_PROGRAM);
    }
}

/**
 * @brief 处理终端升级
 *
 */
static void manager_handle_iote_upgrade(void)
{
    manager_calc_single_block_send_time();

    manager_set_ota_packet_type(PACKET_TYPE_UPGRADE_DATA);

    if (RT_NULL == g_ota_info.send_end_timer)
    {
        g_ota_info.send_end_timer = rt_timer_create("send_end_timer",
                                                    manager_handle_ota_send_end_msg,
                                                    RT_NULL,
                                                    g_ota_info.single_block_send_time * 50,
                                                    RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
        RT_ASSERT(g_ota_info.send_end_timer);
    }

    if (RT_NULL == g_ota_info.sending_timer)
    {
        g_ota_info.sending_timer = rt_timer_create("sending_timer",
                                                   manager_handle_ota_sending_msg,
                                                   RT_NULL,
                                                   g_ota_info.single_block_send_time,
                                                   RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
        RT_ASSERT(g_ota_info.sending_timer);
    }

    g_ota_info.block_count = g_ota_info.upgrade_info.file_size / OTA_BLOCK_SIZE;
    if (g_ota_info.upgrade_info.file_size % OTA_BLOCK_SIZE != 0)
    {
        g_ota_info.block_count++;
    }
    g_ota_info.upgrade_info.upgrade_time = ((g_ota_info.block_count + 3) * g_ota_info.single_block_send_time);

    TRACE_I("iote_upgrade_info:");
    TRACE_I("block_count   %d", g_ota_info.block_count);
    TRACE_I("file_name     %s", g_ota_info.file_name);
    TRACE_I("file_size     %d", g_ota_info.upgrade_info.file_size);
    TRACE_I("device_type   %s", g_ota_info.upgrade_info.device_type);
    TRACE_I("new_version   %s", g_ota_info.upgrade_info.new_version);
    TRACE_I("old_version   %s", g_ota_info.upgrade_info.old_version);
    TRACE_I("upgrade_type  %d", g_ota_info.upgrade_info.upgrade_type);
    TRACE_I("upgrade_range %d", g_ota_info.upgrade_info.upgrade_range);
    TRACE_I("upgrade_num   %d", g_ota_info.upgrade_info.upgrade_num);
    TRACE_I("packet_type   %d", g_ota_info.upgrade_info.packet_type);
    TRACE_I("md5           %s", g_ota_info.upgrade_info.md5);

    manager_send_single_block_ota_data();
    manager_sending_timer_start();

    manager_set_ota_state(OTA_STATE_SENDING);
    TRACE_I("iote ota_upgrade begins");
}

/**
 * @brief 设置缺失数据偏移地址
 *
 * @param missing_data_offset 缺失数据偏移地址
 * @param missing_data_num    缺失数据个数
 * @return unsigned int       0表示无缺失数据或重复缺失数据，大于0表示有缺失数据
 */
static unsigned int manager_set_missing_data(unsigned int *missing_data_offset, unsigned int missing_data_num)
{
    unsigned int offset = 0;

    for (int num = 0; num < missing_data_num; num++)
    {
        offset = missing_data_offset[num] / OTA_BLOCK_SIZE;

        if (0x0 == JUDGMENT_BIT(g_ota_info.mask_map[offset / 8], offset % 8))
        {
            TRACE_I("iote ota_upgrade set_missing_data, offset %d, mask_map[%d] = 0x%x", offset, offset / 8, g_ota_info.mask_map[offset / 8]);
            SET_BIT(g_ota_info.mask_map[offset / 8], offset % 8);
            g_ota_info.miss_data_num++;
        }
    }

    return g_ota_info.miss_data_num;
}

/**
 * @brief 获取缺失数据偏移地址
 *
 * @return unsigned int 缺失数据偏移地址
 */
static unsigned int manager_get_missing_data(void)
{
    unsigned int missing_data_addr = 0;
    unsigned int offset = 0;

    for (offset = 0; offset < g_ota_info.block_count; offset++)
    {
        if (0x1 == JUDGMENT_BIT(g_ota_info.mask_map[offset / 8], offset % 8))
        {
            TRACE_I("iote ota_upgrade get_missing_data offset %d, mask_map[%d] = 0x%x", offset, offset / 8, g_ota_info.mask_map[offset / 8]);
            CLEAR_BIT(g_ota_info.mask_map[offset / 8], offset % 8);
            g_ota_info.miss_data_num--;
            break;
        }
    }

    missing_data_addr = offset * OTA_BLOCK_SIZE;

    return missing_data_addr;
}

/**
 * @brief OTA发送完成后，会发送此消息通知终端网关侧OTA数据已全部发送完毕，终端会根据这个消息核对收包是否完整，
 *        不完整将会发送丢失包请求给网关
 *
 * @param state 升级状态，0表示OTA发送完成，1表示正在升级，2表示不需要升级
 */
static void manager_send_ota_end_msg_to_iote(ota_upgrade_state_e state)
{
    app_ps_ota_upgrade_state_t ota_upgrade_state = {0};
    app_ps_header_t ps_header = {0};
    unsigned char *state_data = RT_NULL;
    unsigned int state_data_len = 0;
    unsigned char gw_verity = uc_static_get_gateway_auth_cfg()->gw_verity;
    unsigned int gw_dev_id = uc_static_get_gateway_base_cfg()->dev_id;

    ota_upgrade_state.upgrade_type = g_ota_info.upgrade_info.upgrade_type;
    rt_memcpy(ota_upgrade_state.new_version, g_ota_info.upgrade_info.new_version, sizeof(g_ota_info.upgrade_info.new_version));
    rt_memcpy(ota_upgrade_state.old_version, g_ota_info.upgrade_info.old_version, sizeof(g_ota_info.upgrade_info.old_version));
    rt_memcpy(ota_upgrade_state.device_type, g_ota_info.upgrade_info.device_type, sizeof(g_ota_info.upgrade_info.device_type));
    ota_upgrade_state.process_state = state;

    ps_header.cmd_type = OTA_UPGRADE_STATE;
    if (gw_verity)
    {
        app_set_header_property(PRO_SRC_ADDR, 1, &ps_header.property);
        ps_header.addr.src_addr = gw_dev_id;
    }

    if (0 != app_data_coding(&ps_header, (unsigned char *)&ota_upgrade_state, sizeof(app_ps_ota_upgrade_state_t), &state_data, &state_data_len))
    {
        TRACE_E("iote ota_upgrade end msg coding fail");
        manager_set_ota_state(OTA_STATE_STOP);
        return;
    }

    if (0 != manager_send_to_wiota(GATEWAY_MANAGER_MODULE,
                                   WIOTA_APP_SEND_OTA,
                                   0,
                                   0,
                                   0,
                                   state_data,
                                   state_data_len,
                                   RT_NULL))
    {
        rt_free(state_data);
    }

    TRACE_I("iote ota_upgrade send end msg");
}

/**
 * @brief OTA升级包编码，准备发往终端
 *
 * @param ota_data     编码后的OTA数据包
 * @param ota_data_len 编码后的OTA数据包长度
 * @return int         0表示成功，非0表示失败
 */
static int manager_ota_upgrade_data_coding(unsigned char **ota_data, unsigned int *ota_data_len)
{
    app_ps_header_t ps_header = {0};
    unsigned int file_size = g_ota_info.upgrade_info.file_size;
    unsigned int block_size = OTA_BLOCK_SIZE;
    unsigned int coding_len = 0;
    unsigned char gw_verity = uc_static_get_gateway_auth_cfg()->gw_verity;
    unsigned int gw_dev_id = uc_static_get_gateway_base_cfg()->dev_id;
    unsigned int last_packet_len = 0;

    if (g_ota_info.send_miss_data)
    {
        if (g_ota_info.miss_data_num == 0)
        {
            TRACE_E("iote ota_upgrade miss data send end");
            return 1;
        }
        else
        {
            g_ota_info.ota_op_address = OTA_OP_ADDRESS + manager_get_missing_data();
        }
    }

    if ((g_ota_info.ota_op_address - OTA_OP_ADDRESS + OTA_BLOCK_SIZE > file_size) &&
        (g_ota_info.ota_op_address - OTA_OP_ADDRESS < file_size))
    {
        last_packet_len = file_size - (g_ota_info.ota_op_address - OTA_OP_ADDRESS);
        g_ota_info.sending_total_len += last_packet_len;
        block_size = RT_ALIGN(last_packet_len, 4);
        TRACE_I("iote ota_upgrade sending offset 0x%x, block_size %d", g_ota_info.ota_op_address - OTA_OP_ADDRESS, block_size);
    }
    else if (g_ota_info.ota_op_address - OTA_OP_ADDRESS >= file_size)
    {
        TRACE_I("iote ota_upgrade data send end");
        return 1;
    }
    else
    {
        g_ota_info.sending_total_len += block_size;
    }

    rt_memset(g_ota_info.upgrade_info.data, 0, sizeof(g_ota_info.upgrade_info.data));
    if (block_size != fal_partition_read(get_down_partition(), g_ota_info.ota_op_address, g_ota_info.upgrade_info.data, block_size))
    {
        TRACE_E("iote ota_upgrade fal_partition_read fail");
        return 2;
    }
    g_ota_info.ota_op_address += block_size;
    g_ota_info.upgrade_info.data_offset = g_ota_info.ota_op_address - OTA_OP_ADDRESS - block_size;
    g_ota_info.upgrade_info.data_length = block_size;

    ps_header.cmd_type = OTA_UPGRADE_REQ;
    if (gw_verity)
    {
        app_set_header_property(PRO_SRC_ADDR, 1, &ps_header.property);
        ps_header.addr.src_addr = gw_dev_id;
    }
    app_set_header_property(PRO_COMPRESS_FLAG, 1, &ps_header.property);
    coding_len = sizeof(app_ps_ota_upgrade_info_t) - (sizeof(g_ota_info.upgrade_info.data) - g_ota_info.upgrade_info.data_length);

    if (0 != app_data_coding(&ps_header, (unsigned char *)&g_ota_info.upgrade_info, coding_len, ota_data, ota_data_len))
    {
        TRACE_E("iote ota_upgrade coding fail");
        g_ota_info.ota_op_address -= block_size;
        return 3;
    }

    if (PACKET_TYPE_UPGRADE_DATA == g_ota_info.upgrade_info.packet_type)
    {
        TRACE_I("iote ota_upgrade %d%%", g_ota_info.sending_total_len * 100 / file_size);
    }

    return 0;
}

/**
 * @brief 处理下行OTA升级请求消息
 *
 * @param from_module 来自哪个线程的命令，一般为net
 * @param upgrade_req OTA升级请求消息结构体指针
 */
void manager_handle_ota_upgrade_req_msg(int from_module, ota_upgrade_req_t *upgrade_req)
{
    ota_state_e ota_state = manager_get_ota_state();
    if (OTA_STATE_DEFAULE != ota_state && OTA_STATE_STOP != ota_state)
    {
        TRACE_E("reject duplicate ota_upgrade_req, ota_state %d", ota_state);
        rt_free(upgrade_req);
        return;
    }

    if (0 == rt_memcmp(upgrade_req->ota_info.device_type, "gateway", rt_strlen("gateway")) ||
        0 == rt_memcmp(upgrade_req->ota_info.device_type, "GATEWAY", rt_strlen("GATEWAY")))
    {
        if (0 != rt_strcmp(upgrade_req->ota_info.old_version, CFG_SOFTWARE_VERSION) ||
            0 == rt_strcmp(upgrade_req->ota_info.new_version, CFG_SOFTWARE_VERSION))
        {
            TRACE_W("%s not required to upgrade", upgrade_req->ota_info.device_type);
            TRACE_W("new ver:%s", upgrade_req->ota_info.new_version);
            TRACE_W("old ver:%s, %s", upgrade_req->ota_info.old_version, CFG_SOFTWARE_VERSION);
            rt_free(upgrade_req);
            return;
        }
    }

    if (0 == rt_memcmp(upgrade_req->ota_info.device_type, "iote", rt_strlen("iote")) ||
        0 == rt_memcmp(upgrade_req->ota_info.device_type, "IOTE", rt_strlen("IOTE")))
    {
        // 鉴权列表为空，不需要升级
        if (manager_auth_list_is_empty())
        {
            TRACE_W("auth is empty, not required to upgrade");
            rt_free(upgrade_req);
            return;
        }
    }

    TRACE_I("ota upgrade device_type %s", upgrade_req->ota_info.device_type);

    app_ps_ota_upgrade_info_t *upgrade_info = &g_ota_info.upgrade_info;

    upgrade_info->upgrade_type = upgrade_req->ota_info.upgrade_type;
    upgrade_info->upgrade_range = upgrade_req->ota_info.upgrade_range;
    upgrade_info->upgrade_num++;

    rt_memcpy(upgrade_info->iote_list, upgrade_req->ota_info.iote_list, sizeof(upgrade_req->ota_info.iote_list));
    rt_memcpy(upgrade_info->new_version, upgrade_req->ota_info.new_version, sizeof(upgrade_req->ota_info.new_version));
    rt_memcpy(upgrade_info->old_version, upgrade_req->ota_info.old_version, sizeof(upgrade_req->ota_info.old_version));
    rt_memcpy(upgrade_info->device_type, upgrade_req->ota_info.device_type, sizeof(upgrade_req->ota_info.device_type));
    rt_memcpy(upgrade_info->md5, upgrade_req->ota_info.md5, sizeof(upgrade_req->ota_info.md5));

    if (upgrade_req->active_state)
    {
        if (0 != module_queue_communication(module_get_queue(from_module),
                                            GATEWAY_MANAGER_MODULE,
                                            from_module,
                                            NET_OTA_DOWNLOAD_REQUEST,
                                            (void *)upgrade_req))
        {
            TRACE_E("ota_upgrade_req send queue fail");
            rt_free(upgrade_req);
        }
        else
        {
            manager_set_ota_state(OTA_STATE_REQ);
        }
    }
}

/**
 * @brief 处理OTA升级响应消息，一般为http将OTA数据包下载完成后的通知消息
 *
 * @param from_module 来自哪个线程的命令，一般为net
 * @param upgrade_res OTA升级响应消息结构体指针
 */
void manager_handle_ota_upgrade_res_msg(int from_module, ota_upgrade_res_t *upgrade_res)
{
    if (0 != upgrade_res->download_state)
    {
        TRACE_E("http download ota file failed");
        manager_set_ota_state(OTA_STATE_STOP);
        return;
    }

    manager_set_ota_state(OTA_STATE_RES);

    rt_memcpy(g_ota_info.file_name, upgrade_res->file_name, sizeof(upgrade_res->file_name));

    if (0 == rt_strcmp("gateway", g_ota_info.upgrade_info.device_type) ||
        0 == rt_strcmp("GATEWAY", g_ota_info.upgrade_info.device_type))
    {
        manager_handle_gateway_upgrade(upgrade_res->file_size);
    }
    else
    {
        g_ota_info.upgrade_info.file_size = upgrade_res->file_size;
        g_ota_info.ota_op_address = OTA_OP_ADDRESS;
        manager_handle_iote_upgrade();
    }

    rt_free(upgrade_res);
}

/**
 * @brief 处理OTA数据包发送消息，发送OTA数据包到WIoTa APP线程
 *
 */
void manager_handle_ota_upgrade_data_sending_msg(void)
{
    unsigned char *ota_data = RT_NULL;
    unsigned int ota_data_len = 0;

    int res = manager_ota_upgrade_data_coding(&ota_data, &ota_data_len);
    if (0 == res) // 发送数据
    {
        g_ota_info.error_cnt = 0;
        if (0 != manager_send_to_wiota(GATEWAY_MANAGER_MODULE,
                                       WIOTA_APP_SEND_OTA,
                                       0,
                                       0,
                                       0,
                                       ota_data,
                                       ota_data_len,
                                       RT_NULL))
        {
            rt_free(ota_data);
            g_ota_info.ota_op_address -= g_ota_info.upgrade_info.data_length;
        }
    }
    else if (1 == res) // 数据发送完成
    {
        if (g_ota_info.send_miss_data)
        {
            manager_set_send_missing_data(RT_FALSE);
            manager_sending_timer_stop();
        }
        else
        {
            manager_send_ota_end_msg_to_iote(OTA_UPGRADE_END);
            manager_set_ota_state(OTA_STATE_SEND_END);
            manager_set_ota_packet_type(PACKET_TYPE_MISSING_DATA);
            manager_sending_timer_stop();
            manager_send_end_timer_start();
        }
    }
    else // 出错
    {
        g_ota_info.error_cnt++;
        if (g_ota_info.error_cnt > OTA_MAX_ERROR_CNT)
        {
            TRACE_E("iote ota_upgrade error, stop now!");
            manager_set_ota_state(OTA_STATE_STOP);
        }
    }
}

/**
 * @brief 处理终端上报的OTA升级缺失数据请求
 *
 * @param missing_data_req 缺失数据请求消息结构体指针
 */
void manager_handle_missing_data_req_msg(app_ps_missing_data_req_t *missing_data_req)
{
    ota_state_e ota_state = manager_get_ota_state();

    if (OTA_STATE_SEND_END != ota_state)
    {
        TRACE_E("not require to handle miss_data_req, ota_state %d", ota_state);
        return;
    }

    if (missing_data_req->miss_data_num > APP_MAX_MISSING_DATA_BLOCK_NUM)
    {
        TRACE_E("miss_data_num %d too large", missing_data_req->miss_data_num);
        return;
    }
    app_ps_ota_upgrade_info_t *upgrade_info = &g_ota_info.upgrade_info;

    if (0 == rt_memcmp(upgrade_info->device_type, EXTERN_MCU, rt_strlen(EXTERN_MCU)) || // 如果是用作外部mcu升级，不做版本检查
        (0 == rt_memcmp(missing_data_req->old_version, upgrade_info->old_version, sizeof(upgrade_info->old_version)) &&
         0 == rt_memcmp(missing_data_req->new_version, upgrade_info->new_version, sizeof(upgrade_info->new_version)) &&
         0 == rt_memcmp(missing_data_req->device_type, upgrade_info->device_type, sizeof(upgrade_info->device_type)) &&
         missing_data_req->upgrade_type == upgrade_info->upgrade_type))
    {
        if (0 < manager_set_missing_data(missing_data_req->miss_data_offset, missing_data_req->miss_data_num))
        {
            manager_set_send_missing_data(RT_TRUE);
            manager_send_end_timer_reset();
            manager_send_single_block_ota_data();
            manager_sending_timer_start();
        }
    }
    else
    {
        TRACE_E("invalid missing_data_req,device_type %s old_version %s new_version %s misdevice %s",
                upgrade_info->device_type,
                missing_data_req->old_version,
                missing_data_req->new_version,
                missing_data_req->device_type);
    }
}

/**
 * @brief 处理终端OTA升级完成消息
 *
 */
void manager_handle_ota_upgrade_complete_msg(void)
{
    manager_send_end_timer_stop();
    manager_send_end_timer_del();
    manager_sending_timer_stop();
    manager_sending_timer_del();

    ota_upgrade_complete_t *cmp_info = rt_malloc(sizeof(ota_upgrade_complete_t));
    RT_ASSERT(cmp_info);
    rt_memset(cmp_info, 0, sizeof(ota_upgrade_complete_t));

    rt_memcpy(cmp_info->new_version, g_ota_info.upgrade_info.new_version, sizeof(cmp_info->new_version));
    rt_memcpy(cmp_info->old_version, g_ota_info.upgrade_info.old_version, sizeof(cmp_info->old_version));
    rt_memcpy(cmp_info->device_type, g_ota_info.upgrade_info.device_type, sizeof(cmp_info->device_type));
    rt_memcpy(cmp_info->note, OTA_UPGREADE_COMPLETE_NOTE, rt_strlen(OTA_UPGREADE_COMPLETE_NOTE));

    if (0 != module_queue_communication(module_get_queue(NET_APP_MODULE),
                                        GATEWAY_MANAGER_MODULE,
                                        NET_APP_MODULE,
                                        NET_OTA_UPGRADE_COMPLETE,
                                        (void *)cmp_info))
    {
        TRACE_E("ota_upgrade_cmp send queue fail");
        rt_free(cmp_info);
    }
    manager_set_ota_state(OTA_STATE_STOP);

    rt_memset(&g_ota_info, 0, sizeof(ota_upgrade_info_t));
    g_ota_info.ota_op_address = OTA_OP_ADDRESS;

    TRACE_I("iote ota_upgrade completed, ver %s", cmp_info->new_version);
}